<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        
        <meta name="author" content="隐星魂 (Roy.Sun)">
        
        <link rel="shortcut icon" href="../../img/favicon.ico">
        <title>6.调度器 - 玄武操作系统</title>
        <link href="../../css/bootstrap.min.css" rel="stylesheet">
        <link href="../../css/font-awesome.min.css" rel="stylesheet">
        <link href="../../css/base.css" rel="stylesheet">
        <link rel="stylesheet" href="https://cdn.staticfile.org/highlight.js/10.0.3/styles/color-brewer.min.css">

        <script src="../../js/jquery-1.10.2.min.js" defer></script>
        <script src="../../js/bootstrap.min.js" defer></script>
        <script src="https://cdn.staticfile.org/highlight.js/10.0.3/highlight.min.js"></script>
        <script>hljs.initHighlightingOnLoad();</script> 
    </head>

    <body>
        <div class="navbar fixed-top navbar-expand-lg navbar-dark bg-primary">
            <div class="container">
                <a class="navbar-brand" href="../..">玄武操作系统</a>
                <!-- Expander button -->
                <button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbar-collapse">
                    <span class="navbar-toggler-icon"></span>
                </button>

                <!-- Expanded navigation -->
                <div id="navbar-collapse" class="navbar-collapse collapse">
                        <!-- Main navigation -->
                        <ul class="nav navbar-nav">
                            <li class="navitem">
                                <a href="../.." class="nav-link">主页</a>
                            </li>
                            <li class="navitem">
                                <a href="../../License/" class="nav-link">开源协议</a>
                            </li>
                            <li class="dropdown">
                                <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">快速开发指南 <b class="caret"></b></a>
                                <ul class="dropdown-menu">
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">STM32</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../QuickGuide/stm32/01-Envsetup-Guide/" class="dropdown-item">01-开发环境搭建指南</a>
</li>
            
<li>
    <a href="../../QuickGuide/stm32/02-atkh743/" class="dropdown-item">02-正点原子阿波罗H743开发板上手指南</a>
</li>
            
<li>
    <a href="../../QuickGuide/stm32/03-fk429m/" class="dropdown-item">03-反客F429核心板上手指南</a>
</li>
            
<li>
    <a href="../../QuickGuide/stm32/04-atkf103core/" class="dropdown-item">04-正点原子F103核心板上手指南</a>
</li>
            
<li>
    <a href="../../QuickGuide/stm32/05-atkf407core/" class="dropdown-item">05-正点原子F407核心板上手指南</a>
</li>
            
<li>
    <a href="../../QuickGuide/stm32/06-WeActH750/" class="dropdown-item">06-微行电子H750开发板上手指南</a>
</li>
            
<li>
    <a href="../../QuickGuide/stm32/07-Project-From-Scratch-Guide/" class="dropdown-item">07-自定义工程配置指南</a>
</li>
    </ul>
  </li>
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">GD32</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../QuickGuide/gd32/01-Envsetup-Guide/" class="dropdown-item">01-开发环境搭建指南</a>
</li>
            
<li>
    <a href="../../QuickGuide/gd32/02-Project-Setup-Guide/" class="dropdown-item">02-工程配置指南</a>
</li>
    </ul>
  </li>
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">GD32V</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../QuickGuide/gd32v/01-Envsetup-Guide/" class="dropdown-item">01-开发环境搭建指南</a>
</li>
            
<li>
    <a href="../../QuickGuide/gd32v/02-Project-Setup-Guide/" class="dropdown-item">02-工程配置指南</a>
</li>
    </ul>
  </li>
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">NXP S32K</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../QuickGuide/s32k/01-Envsetup-Guide/" class="dropdown-item">01-开发环境搭建指南</a>
</li>
            
<li>
    <a href="../../QuickGuide/s32k/02-Project-Setup-Guide/" class="dropdown-item">02-工程配置指南</a>
</li>
    </ul>
  </li>
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">玄武内核模块</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../QuickGuide/xwko/01-XuanWuKO-Guide/" class="dropdown-item">01-上手指南</a>
</li>
    </ul>
  </li>
                                </ul>
                            </li>
                            <li class="dropdown active">
                                <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">应用手册 <b class="caret"></b></a>
                                <ul class="dropdown-menu">
                                    
<li>
    <a href="../00-Index/" class="dropdown-item">0.目录</a>
</li>
                                    
<li>
    <a href="../01-Brief/" class="dropdown-item">1.简介</a>
</li>
                                    
<li>
    <a href="../02-Basic-System-Architecture/" class="dropdown-item">2.系统基本架构</a>
</li>
                                    
<li>
    <a href="../03-Build-System/" class="dropdown-item">3.构建系统</a>
</li>
                                    
<li>
    <a href="../04-Boot-Flow/" class="dropdown-item">4.启动流程</a>
</li>
                                    
<li>
    <a href="../05-IRQ/" class="dropdown-item">5.中断控制</a>
</li>
                                    
<li>
    <a href="./" class="dropdown-item active">6.调度器</a>
</li>
                                    
<li>
    <a href="../07-Thread/" class="dropdown-item">7.线程</a>
</li>
                                    
<li>
    <a href="../08-SWT/" class="dropdown-item">8.软件定时器</a>
</li>
                                    
<li>
    <a href="../09-PM/" class="dropdown-item">9.电源管理</a>
</li>
                                    
<li>
    <a href="../10-Lock/" class="dropdown-item">10.锁</a>
</li>
                                    
<li>
    <a href="../11-Sync/" class="dropdown-item">11.同步</a>
</li>
                                    
<li>
    <a href="../12-MM/" class="dropdown-item">12.内存管理</a>
</li>
                                    
<li>
    <a href="../13-C-Lib/" class="dropdown-item">13.玄武C库</a>
</li>
                                </ul>
                            </li>
                            <li class="dropdown">
                                <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">Lua手册 <b class="caret"></b></a>
                                <ul class="dropdown-menu">
                                    
<li>
    <a href="../../LuaManual/00-Index/" class="dropdown-item">0.目录</a>
</li>
                                    
<li>
    <a href="../../LuaManual/01-Brief/" class="dropdown-item">1.简介</a>
</li>
                                    
<li>
    <a href="../../LuaManual/02-XWXT/" class="dropdown-item">2.全局导出表</a>
</li>
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">3.XWOS内核</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../LuaManual/03-XWOS/01-SDK/" class="dropdown-item">3.1.线程库</a>
</li>
            
<li>
    <a href="../../LuaManual/03-XWOS/02-Spinlock/" class="dropdown-item">3.2.自旋锁库</a>
</li>
            
<li>
    <a href="../../LuaManual/03-XWOS/03-Seqlock/" class="dropdown-item">3.3.顺序锁库</a>
</li>
            
<li>
    <a href="../../LuaManual/03-XWOS/04-Mutex/" class="dropdown-item">3.4.互斥锁库</a>
</li>
            
<li>
    <a href="../../LuaManual/03-XWOS/05-Semaphore/" class="dropdown-item">3.5.信号量库</a>
</li>
            
<li>
    <a href="../../LuaManual/03-XWOS/06-Condition/" class="dropdown-item">3.6.条件量库</a>
</li>
            
<li>
    <a href="../../LuaManual/03-XWOS/07-Flag/" class="dropdown-item">3.7.事件标志库</a>
</li>
            
<li>
    <a href="../../LuaManual/03-XWOS/08-Barrier/" class="dropdown-item">3.8.线程栅栏库</a>
</li>
            
<li>
    <a href="../../LuaManual/03-XWOS/09-Selector/" class="dropdown-item">3.9.信号选择器库</a>
</li>
            
<li>
    <a href="../../LuaManual/03-XWOS/10-PM/" class="dropdown-item">3.10.电源管理</a>
</li>
    </ul>
  </li>
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">4.玄武Lua函数库</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../LuaManual/04-XWLIB/01-Bitmap/" class="dropdown-item">4.1.位图</a>
</li>
    </ul>
  </li>
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">5.设备栈</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../LuaManual/05-XWDS/01-Soc/" class="dropdown-item">5.1.SOC</a>
</li>
            
<li>
    <a href="../../LuaManual/05-XWDS/02-GPIO/" class="dropdown-item">5.2.GPIO</a>
</li>
            
<li>
    <a href="../../LuaManual/05-XWDS/03-UART/" class="dropdown-item">5.3.UART</a>
</li>
            
<li>
    <a href="../../LuaManual/05-XWDS/04-SPI-Master/" class="dropdown-item">5.4.SPI Master</a>
</li>
            
<li>
    <a href="../../LuaManual/05-XWDS/05-IIC-Master/" class="dropdown-item">5.5.IIC Master</a>
</li>
    </ul>
  </li>
                                </ul>
                            </li>
                            <li class="dropdown">
                                <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">移植笔记 <b class="caret"></b></a>
                                <ul class="dropdown-menu">
                                    
<li>
    <a href="../../PortingNote/00-Index/" class="dropdown-item">目录</a>
</li>
                                    
<li>
    <a href="../../PortingNote/01-Porting-Note/" class="dropdown-item">移植笔记</a>
</li>
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">ARM-Cortex-M</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../PortingNote/02-ARM-Cortex-M/01-ARM-Cortex-M-Porting-Note/" class="dropdown-item">架构移植笔记</a>
</li>
            
<li>
    <a href="../../PortingNote/02-ARM-Cortex-M/02-STM32-Porting-Note/" class="dropdown-item">STM32</a>
</li>
    </ul>
  </li>
                                    
  <li class="dropdown-submenu">
    <a href="#" class="dropdown-item">RISC-V</a>
    <ul class="dropdown-menu">
            
<li>
    <a href="../../PortingNote/03-RISC-V/01-GD32V-Porting-Note/" class="dropdown-item">GD32V</a>
</li>
    </ul>
  </li>
                                </ul>
                            </li>
                            <li class="dropdown">
                                <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">规范 <b class="caret"></b></a>
                                <ul class="dropdown-menu">
                                    
<li>
    <a href="../../Specification/00-Index/" class="dropdown-item">目录</a>
</li>
                                    
<li>
    <a href="../../Specification/01-Git-Commit-Specification/" class="dropdown-item">git-commit规范</a>
</li>
                                    
<li>
    <a href="../../Specification/02-Version-Branch-Specification/" class="dropdown-item">版本分支规范</a>
</li>
                                </ul>
                            </li>
                        </ul>

                    <ul class="nav navbar-nav ml-auto">
                        <li class="nav-item">
                            <a href="#" class="nav-link" data-toggle="modal" data-target="#mkdocs_search_modal">
                                <i class="fa fa-search"></i> 搜索
                            </a>
                        </li>
                            <li class="nav-item">
                                <a rel="prev" href="../05-IRQ/" class="nav-link">
                                    <i class="fa fa-arrow-left"></i> 上一篇
                                </a>
                            </li>
                            <li class="nav-item">
                                <a rel="next" href="../07-Thread/" class="nav-link">
                                    下一篇 <i class="fa fa-arrow-right"></i>
                                </a>
                            </li>
                    </ul>
                </div>
            </div>
        </div>

        <div class="container">
            <div class="row">
                    <div class="col-md-3"><div class="navbar-light navbar-expand-md bs-sidebar hidden-print affix" role="complementary">
    <div class="navbar-header">
        <button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#toc-collapse" title="Table of Contents">
            <span class="fa fa-angle-down"></span>
        </button>
    </div>

    
    <div id="toc-collapse" class="navbar-collapse collapse card bg-secondary">
        <ul class="nav flex-column">
            
            <li class="nav-item" data-level="1"><a href="#6" class="nav-link">6.调度器</a>
              <ul class="nav flex-column">
            <li class="nav-item" data-level="2"><a href="#61" class="nav-link">6.1.描述</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#62" class="nav-link">6.2.用法</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#63" class="nav-link">6.3.配置</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#64api" class="nav-link">6.4.API参考</a>
              <ul class="nav flex-column">
              </ul>
            </li>
            <li class="nav-item" data-level="2"><a href="#65" class="nav-link">6.5.附录</a>
              <ul class="nav flex-column">
              </ul>
            </li>
              </ul>
            </li>
        </ul>
    </div>
</div></div>
                    <div class="col-md-9" role="main">

<h1 id="6">6.调度器</h1>
<h2 id="61">6.1.描述</h2>
<ul>
<li>玄武OS调度器最基本的调度单位是<strong>线程</strong>，没有<strong>进程</strong>的概念，也不支持使用MMU
    管理虚拟内存；</li>
<li>每个<strong>线程</strong>都有自己独立的<strong>栈</strong>内存，但所有内存对所有线程都可见，除非使用
    MPU增加限制；</li>
<li>每个<strong>线程</strong>都有调度优先级，优先级的值越<strong>小</strong>，优先级越<strong>低</strong>，玄武OS定义了
    几个代表最大优先级、最小优先级的宏，应该在应用中使用这些宏，以提高修改
    系统优先级配置后的整体兼容性。</li>
<li>调度器始终选择优先级最高的线程，高优先级的线程可以抢占低优先级的线程。</li>
<li>相同的优先级的线程，调度器按照先进先出的方法调度，同优先级线程之间不能相互抢占。</li>
<li>调度器支持电源管理；</li>
<li>每个CPU都有自己独立的调度器，线程只能在特定CPU的调度器中调度，不能随意跨越CPU，
    如果需要跨越CPU，需要进行<strong>迁移</strong>操作；</li>
</ul>
<h3 id="_1">调度算法</h3>
<h4 id="_2">数据类型</h4>
<ul>
<li>每个优先级都有一个先进先出(FIFO)的<strong>就绪</strong>队列；</li>
<li>
<p>使用一个位图标记每个优先级队列是否为空；非空的队列对应的位被置1，否则被清0。</p>
<p><img alt="img" src="../res/figure/ready-queue.png" title="玄武OS调度器就绪队列" /></p>
</li>
</ul>
<h4 id="_3">调度流程</h4>
<ul>
<li>
<p>定义操作<strong>fls</strong>：从最高位起查找第一个被置1的位，并返回其序号，
    如果所有位都为0，返回-1。此操作需要CPU的相关指令来实现，例如ARM的clz，
    DEC Alpha的ctlz，x86的lzcnt，PowerPC的cntlz等。</p>
</li>
<li>
<p>流程图</p>
<p><img alt="img" src="../res/figure/sched-flow.png" title="玄武OS调度流程图" /></p>
</li>
</ul>
<h2 id="62">6.2.用法</h2>
<h3 id="621">6.2.1.调度器中的特殊任务</h3>
<h4 id="_4">空闲任务</h4>
<p><a id="SKD-IDLE-TASK"></a></p>
<p>当调度器中没有任何线程<strong>就绪</strong>，调度器会调度空闲任务。
空闲任务比较特殊，属于<strong>最低优先级</strong>的线程，但不能使用任何会导致睡眠、阻塞的函数。
用户可在空闲任务中增加用户代码，方法：</p>
<ul>
<li>在配置文件<code>xwbd/电路板名称/cfg/board.h</code>中定义配置<code>BRDCFG_XWSKD_IDLE_HOOK</code>
    为<code>1</code>；</li>
<li>定义函数<code>bdl_xwskd_idle_hook()</code>并在其中增加用户代码。</li>
</ul>
<h4 id="_5">中断底半部任务</h4>
<p><a id="SKD-BH-TASK"></a></p>
<p>当调度器配置<code>XWMPCFG_SD_BH</code>或<code>XWUPCFG_SD_BH</code>为1，调度器会为系统预留一个
<strong>最高优先级</strong>线程。中断底半部任务比较特殊，属于线程上下文，
但不能使用任何会导致睡眠、阻塞的函数。中断底半部任务可抢占任何线程。
当开启中断底半部时，调度器的滴答定时器任务运行在中断底半部中。
当前，玄武OS的中断底半部并未完全开发完成，目前只开放给滴答定时器任务使用。</p>
<h4 id="_6">滴答定时器任务</h4>
<p><a id="SKD-HWT-TASK"></a></p>
<p>操作系统内核都会包含一个定时器，用于产生固定周期的“<strong>滴答</strong>”（或称为“<strong>节拍</strong>”）中断。
滴答定时器任务也即是在此定时器中断中执行的任务。
如果<a href="#SKD-BH-TASK">中断底半部任务</a>配置为<strong>启用</strong>，滴答定时器任务运行在中断底半部任务内部；
如果<a href="#SKD-BH-TASK">中断底半部任务</a>配置为<strong>禁用</strong>，滴答定时器任务运行在中断上下文中。</p>
<p>用户也可以在滴答定时器任务中增加自己的代码，方法：</p>
<ul>
<li>在配置文件<code>xwbd/电路板名称/cfg/board.h</code>中定义配置<code>BRDCFG_XWSKD_SYSHWT_HOOK</code>
    为<code>1</code>；</li>
<li>定义函数<code>bdl_xwskd_syshwt_hook()</code>并在其中增加用户代码。</li>
</ul>
<h3 id="622">6.2.2.调度器的中断</h3>
<p><a id="SKD-IRQ"></a></p>
<h4 id="_7">切换上下文的中断</h4>
<ul>
<li>描述：调度器用于切换正在执行的线程的中断</li>
<li>中断优先级：最低</li>
</ul>
<h4 id="_8">滴答定时器的中断</h4>
<ul>
<li>描述：用于产生固定周期的“<strong>滴答</strong>”（或称为“<strong>节拍</strong>”）的定时器中断，
    <a href="#SKD-HWT-TASK">滴答定时器任务</a>由此中断触发执行</li>
<li>中断优先级：切换上下文的中断 &lt;= 滴答定时器的中断 &lt; 调度器服务中断</li>
</ul>
<h4 id="_9">调度器服务中断</h4>
<ul>
<li>描述：用于执行调度器特殊操作的软中断，包括：<ul>
<li>调度器暂停 <code>xwos_scheduler_suspend_lic()</code></li>
<li>线程退出 <code>xwos_thrd_exit_lic()</code></li>
<li>线程冻结 <code>xwos_cthrd_freeze_lic()</code></li>
<li>线程解冻 <code>xwos_thrd_thaw_lic()</code></li>
<li>线程迁移 <code>xwos_thrd_outmigrate_lic()</code>和<code>xwos_thrd_immigrate_lic()</code></li>
</ul>
</li>
<li>中断优先级：最高</li>
</ul>
<blockquote>
<p><strong>注意</strong></p>
<p>系统中的其他中断，优先级只能在切换上下文中断与调度器服务中断之间。
其他中断不可抢占调度器服务中断，切换上下文的中断也不能抢占其他中断。</p>
</blockquote>
<h3 id="623">6.2.3.硬件定时器</h3>
<p>在玄武OS内核中，每个CPU都会有一个私有的滴答定时器，产生固定频率的中断
（通常配置为1000HZ，参考配置文件<code>xwbd/电路板名称/cfg/xwos.h</code>中
的<code>XWMPCFG_SYSHWT_PERIOD</code>或<code>XWUPCFG_SYSHWT_PERIOD</code>）。
玄武OS的滴答定时器会产生三个变量：</p>
<ul>
<li><strong>tickcount</strong>滴答计数<ul>
<li>在每个滴答定时器中断中，<strong>tickcount</strong>都会自增1，
    <strong>tickcount</strong>表示滴答定时器中断了多少次；</li>
<li><strong>tickcount</strong>是一个每CPU变量，代码运行在哪个CPU上，访问的就是哪个CPU的
    <strong>tickcount</strong>；</li>
<li>通过API<code>xwos_skd_get_tickcount_lc()</code>可以获取当前CPU的<strong>tickcount</strong>，
    API的后缀"<strong>_lc</strong>"表示此函数是一个"<strong>Local CPU</strong>"函数。</li>
</ul>
</li>
<li><strong>timetick</strong>滴答时间<ul>
<li>玄武OS内核使用的时间(<strong>xwtm_t</strong>)是以<strong>纳秒(ns)</strong>为单位，假设滴答器频率1000HZ，
    <strong>tickcount</strong>每1ms增加一次，1ms为(xwtm_t)1000000，
    <strong>timetick</strong> = <strong>tickcount</strong> × (xwtm_t)1000000；</li>
<li><strong>timetick</strong>是一个每CPU变量，代码运行在哪个CPU上，访问的就是哪个CPU的
    <strong>timetick</strong>；</li>
<li>通过API<code>xwos_skd_get_timetick_lc()</code>可以获取当前CPU的<strong>timetick</strong>，
    API的后缀"<strong>_lc</strong>"表示此函数是一个"<strong>Local CPU</strong>"函数。</li>
</ul>
</li>
<li><strong>timestamp</strong>时间戳<ul>
<li><strong>timestamp</strong>是以纳秒为单位的时间戳。<strong>timestamp</strong>与<strong>timetick</strong>区别是
    <strong>timetick</strong>在1000H在的频率时只能精确到1ms（后6位都为0），
    <strong>timestamp</strong>可以精确到1ns，但这需要SOC的高精度定时器提供支持，
    否则<strong>timestamp</strong>的值与<strong>timetick</strong>相同；</li>
<li><strong>timestamp</strong>是一个每CPU变量，代码运行在哪个CPU上，访问的就是哪个CPU的
    <strong>timestamp</strong>；</li>
<li>通过API<code>xwos_skd_get_timestamp_lc()</code>可以获取当前CPU的<strong>timestamp</strong>，
    API的后缀"<strong>_lc</strong>"表示此函数是一个"<strong>Local CPU</strong>"函数。</li>
</ul>
</li>
</ul>
<h3 id="624">6.2.4.超时管理</h3>
<p><a id="SKD-TM"></a></p>
<h4 id="_10">原理 —— 时间树</h4>
<p>玄武OS内核中，每个需要超时管理的对象（线程、软件定时器）都是以<strong>时间树节点</strong>连接
到时间树中。<strong>时间树节点</strong>中包含了超时的<strong>滴答时间</strong>，调度器每次进入
滴答定时器任务时，都会检测时间树中是否有节点超时。在时间树中，所有节点的滴答
时间都是未来的时间。最先超时的节点的滴答时间一定是最小值。
因此时间树的超时问题是寻找最小值的问题。
玄武OS使用红黑树解决此最小值的问题，因此算法原理被称为时间树：</p>
<ul>
<li>使用一个<strong>leftmost</strong>指针指向最小值，需要时可直接从<strong>leftmost</strong>快速获取。</li>
<li>超时后，<strong>leftmost</strong>从红黑树中被删除，按照二叉树的性质，下一任<strong>leftmost</strong>是
    前任的右孩子（即后继）。如果前任的右孩子为叶子，下一任<strong>leftmost</strong>一定是
    前任的父节点。</li>
<li>红黑树中不允许存在关键字相同的节点，因此拥有相同超时滴答时间的节点相互
    形成链表，超时后它们都被唤醒。</li>
</ul>
<p><img alt="img" src="../res/figure/timetree.png" title="玄武OS时间树" /></p>
<h4 id="api">超时API的统一形式</h4>
<p>当调用带超时管理的API，传入时间参数时，都是通过一个<strong>xwtm_t</strong>类型的指针传入，例如：</p>
<pre><code class="C">/* 睡眠 */
xwer_t xwos_cthrd_sleep(xwtm_t * xwtm);

/* 等待信号量 */
xwer_t xwos_sem_timedwait(struct xwos_sem * sem, xwtm_t * xwtm);

/* 等待条件量 */
xwer_t xwos_cond_timedwait(struct xwos_cond * cond,
                           union xwlk_ulock lock, xwsq_t lktype,
                           void * lkdata, xwtm_t * xwtm, xwsq_t * lkst);

/* 等待互斥锁 */
xwer_t xwos_mtx_timedlock(struct xwos_mtx * mtx, xwtm_t * xwtm);


/* 等待信号旗 */
xwer_t xwos_flg_timedwait(struct xwos_flg * flg, xwsq_t trigger, xwsq_t action,
                          xwbmp_t origin[], xwbmp_t msk[],
                          xwtm_t * xwtm);

/* 选择信号选择器 */
xwer_t xwos_sel_timedselect(struct xwos_sel * sel,
                            xwbmp_t msk[], xwbmp_t trg[],
                            xwtm_t * xwtm);

/* 线程同步 */
xwer_t xwos_br_timedsync(struct xwos_br * br, xwsq_t pos,
                         xwbmp_t sync[], xwtm_t * xwtm);
</code></pre>

<p>这是因为<code>xwtm</code>指向的缓冲区既作为<strong>输入</strong>，又作为<strong>输出</strong>：</p>
<ul>
<li>作为输入时，表示期望的超时时间；</li>
<li>作为输出时，返回剩余的时间。超时后，剩余的时间应该&lt;=0。</li>
</ul>
<p>例如：</p>
<ul>
<li>假设调用<code>xwos_mtx_timedlock()</code>时，<code>disired</code>作为输入，期望等待10s。</li>
<li>4s后就已获得互斥锁，函数返回，<code>disired</code>作为输出，剩余时间为(10 - 4) = 6s。</li>
</ul>
<pre><code class="C">/* 等待互斥锁 */
{
        xwer_t rc;
        xwtm_t disired;

        disired = 10 * XWTM_S;
        rc = xwos_mtx_timedlock(mid, &amp;disired);
        if (XWOK == rc) {
                /* 临界区 */
                xwlogf(INFO, &quot;剩余时间：%lld&quot;, disired);
                xwos_mtx_unlock(mid);
        }
}
</code></pre>

<h2 id="63">6.3.配置</h2>
<h5 id="cfgxwosh">cfg/xwos.h</h5>
<ul>
<li>MP内核配置：<ul>
<li>调度器<ul>
<li><code>XWMPCFG_SYSHWT_PERIOD</code>：硬件定时器周期；</li>
<li><code>XWMPCFG_SKD_PRIORITY_RT_NUM</code>：调度器实时优先级数量；</li>
<li><code>XWMPCFG_SKD_IDLE_STACK_SIZE</code>：空闲任务栈大小；</li>
<li><code>XWMPCFG_SKD_BH</code>：是否启用中断底半部，取值：1|0；</li>
<li><code>XWMPCFG_SKD_BH_STACK_SIZE</code>：中断底半部栈大小；</li>
<li><code>XWMPCFG_SKD_TCB_MEMSLICE</code>：是否启用TCB对象缓存；</li>
<li><code>XWMPCFG_SKD_SWT</code>：是否启用软件定时器，取值：1|0；</li>
<li><code>XWMPCFG_SKD_SWT_MEMSLICE</code>：是否启用软件定时器对象缓存，取值：1|0；</li>
</ul>
</li>
</ul>
</li>
<li>UP内核配置：<ul>
<li>调度器<ul>
<li><code>XWUPCFG_SYSHWT_PERIOD</code>：硬件定时器周期；</li>
<li><code>XWUPCFG_SKD_PRIORITY_RT_NUM</code>：调度器实时优先级数量；</li>
<li><code>XWUPCFG_SKD_IDLE_STACK_SIZE</code>：空闲任务栈大小；</li>
<li><code>XWUPCFG_SKD_BH</code>：是否启用中断底半部，取值：1|0；</li>
<li><code>XWUPCFG_SKD_BH_STACK_SIZE</code>：中断底半部栈大小；</li>
<li><code>XWUPCFG_SKD_PM</code>：是否启用电源管理，取值：1|0；</li>
<li><code>XWUPCFG_SKD_THRD_EXIT</code>：是否启用线程退出，取值：1|0；</li>
<li><code>XWUPCFG_SKD_SWT</code>：是否启用软件定时器，取值：1|0；</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="64api">6.4.API参考</h2>
<ul>
<li>头文件：<code>xwos/osal/skd.h</code></li>
<li>注释：见头文件</li>
</ul>
<h2 id="65">6.5.附录</h2>
<ul>
<li><a href="../00-Index/">返回目录</a></li>
</ul></div>
            </div>
        </div>

        <footer class="col-md-12">
            <hr>
            <p>Documentation built with <a href="https://www.mkdocs.org/">MkDocs</a>.</p>
        </footer>
        <script>
            var base_url = "../..",
                shortcuts = {"help": 191, "next": 78, "previous": 80, "search": 83};
        </script>
        <script src="../../js/base.js" defer></script>
        <script src="../../search/main.js" defer></script>

        <div class="modal" id="mkdocs_search_modal" tabindex="-1" role="dialog" aria-labelledby="searchModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title" id="searchModalLabel">搜索</h4>
                <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
            </div>
            <div class="modal-body">
                <p>
                    在这里所有文档：
                </p>
                <form>
                    <div class="form-group">
                        <input type="search" class="form-control" placeholder="搜索..." id="mkdocs-search-query" title="Type search term here">
                    </div>
                </form>
                <div id="mkdocs-search-results"></div>
            </div>
            <div class="modal-footer">
            </div>
        </div>
    </div>
</div><div class="modal" id="mkdocs_keyboard_modal" tabindex="-1" role="dialog" aria-labelledby="keyboardModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title" id="keyboardModalLabel">Keyboard Shortcuts</h4>
                <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
            </div>
            <div class="modal-body">
              <table class="table">
                <thead>
                  <tr>
                    <th style="width: 20%;">Keys</th>
                    <th>Action</th>
                  </tr>
                </thead>
                <tbody>
                  <tr>
                    <td class="help shortcut"><kbd>?</kbd></td>
                    <td>Open this help</td>
                  </tr>
                  <tr>
                    <td class="next shortcut"><kbd>n</kbd></td>
                    <td>Next page</td>
                  </tr>
                  <tr>
                    <td class="prev shortcut"><kbd>p</kbd></td>
                    <td>Previous page</td>
                  </tr>
                  <tr>
                    <td class="search shortcut"><kbd>s</kbd></td>
                    <td>Search</td>
                  </tr>
                </tbody>
              </table>
            </div>
            <div class="modal-footer">
            </div>
        </div>
    </div>
</div>

    </body>
</html>
